// Fill out your copyright notice in the Description page of Project Settings.


#include "FileTool/CommonFileTool.h"

#include <string>
#include "HAL/PlatformFileManager.h"
#include "LogTool/CommonLogTool.h"
#include "../Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptPlugin.h"
#include "Misc/Paths.h"

using namespace std;

UCommonFileTool::UCommonFileTool()
{
	pfd = nullptr;
	hr = CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd));
}

UCommonFileTool::~UCommonFileTool()
{
}

void UCommonFileTool::GetFilePathWithinFileDialog(FString DialogTitle, FString DefaultPath, TArray<FFileSuffixType> SurffixTypes, bool bSave,
                                                  FString& FilePath)
{
	if (!pfd)
	{
		return;
	}
	if (SurffixTypes.Num() < 1)
	{
		return;
	}
	
	DWORD dwFlags;

	hr = pfd->GetOptions(&dwFlags);
	hr = pfd->SetOptions(dwFlags | FOS_FORCEFILESYSTEM | FOS_ALLOWMULTISELECT);

	
	TArray<COMDLG_FILTERSPEC> fileTypes;
	;
	for (int32 i = 0; i < SurffixTypes.Num(); ++i)
	{
		COMDLG_FILTERSPEC fileType = {*SurffixTypes[i].SuffixName, *SurffixTypes[i].SuffixType};
		
		fileTypes.Add(fileType);
	}
	
	pfd->SetTitle(*DialogTitle);
	
	hr = pfd->SetFileTypes(fileTypes.Num(), fileTypes.GetData());
	hr = pfd->SetFileTypeIndex(1);

	hr = pfd->Show(nullptr);

	IShellItem* pSellItem = nullptr;
	hr = pfd->GetResult(&pSellItem);

	if (pSellItem)
	{
		LPTSTR pszFilePath = nullptr;
		
        hr = pSellItem->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING, &pszFilePath);
    
        FilePath = pszFilePath;
    
        CoTaskMemFree(pszFilePath);
        pSellItem->Release();
	}
}

void UCommonFileTool::CreateFolder(FString DirPath)
{
	if (!IsDirectoryExists(DirPath))
	{
		FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*DirPath);
	}
}

void UCommonFileTool::RenameFile(FString OriginalFileName, FString NewFileName)
{
	// 转换路径为绝对路径
	FString AbsoluteOriginalPath = FPaths::ConvertRelativePathToFull(OriginalFileName);
	FString AbsoluteNewPath = FPaths::GetPath(AbsoluteOriginalPath) / NewFileName;
    
	// 检查新文件名是否已经存在
	bool bFileExists = IFileManager::Get().FileExists(*AbsoluteNewPath);
	if (bFileExists)
	{
		// 如果存在，添加序号避免冲突
		int32 Counter = 1;
		FString BaseNewName = *NewFileName;
		FString Extension = "";
		int32 DotIndex = 0;
		
		BaseNewName.FindLastChar('.', DotIndex);// 找到最后一个'.'的位置
		
		if (DotIndex > 0)
		{
			Extension = BaseNewName.Mid(DotIndex);
			BaseNewName = BaseNewName.Left(DotIndex);
		}
		while (bFileExists)
		{
			NewFileName = BaseNewName + "_" + FString::FromInt(Counter++) + Extension;
			bFileExists = IFileManager::Get().FileExists(*AbsoluteNewPath);
		}
	}
	else if (IFileManager::Get().FileExists(*AbsoluteOriginalPath)) // 检查原文件是否存在
	{
		// 重命名原文件为新文件名
		IFileManager::Get().Move(*AbsoluteOriginalPath, *AbsoluteNewPath);
	}
}

void UCommonFileTool::CopyFile(FString SrcFile, FString DestFile)
{
	IFileManager::Get().Copy(*DestFile, *SrcFile);
}

void UCommonFileTool::GetFileName(const FString& FilePath, FString& FileName)
{
	FileName = FPaths::GetBaseFilename(FilePath) + L"." + FPaths::GetExtension(FilePath);
}

void UCommonFileTool::ReadFileToString(const FString& FilePath, FString& FileContent)
{
	if (IFileManager::Get().FileExists(*FilePath))
	{
		FFileHelper::LoadFileToString(FileContent, *FilePath);
	}
}

bool UCommonFileTool::IsDirectoryExists(const FString& DirPath) const
{
	return FPlatformFileManager::Get().GetPlatformFile().DirectoryExists(*DirPath);
}

void UCommonFileTool::RemoveFilesWithinDirectory(const FString& TargetDir)
{
	char szCurPath[MAX_PATH];		//用于定义搜索格式
	FString DirTarget(TargetDir);
	std::string TmpDirPath = TCHAR_TO_ANSI(*DirTarget);
	
	_snprintf_s(szCurPath, MAX_PATH, "%s//*.*", TmpDirPath.c_str());	//匹配格式为*.*,即该目录下的所有文件
	WIN32_FIND_DATAA FindFileData;		
	ZeroMemory(&FindFileData, sizeof(WIN32_FIND_DATAA));
	HANDLE hFile = FindFirstFileA(szCurPath, &FindFileData);
	bool IsFinded = true;
	
	while(IsFinded)
	{
		IsFinded = FindNextFileA(hFile, &FindFileData);	//递归搜索其他的文件
		if( strcmp(FindFileData.cFileName, ".") && strcmp(FindFileData.cFileName, "..") ) //如果不是"." ".."目录
		{
			string strFileName = "";
			strFileName = strFileName + TmpDirPath.c_str() + "//" + FindFileData.cFileName;
			string strTemp;
			strTemp = strFileName;
			if( IsDirectoryExists(strFileName.c_str()) ) //如果是目录，则递归地调用
			{	
				printf("目录为:%s/n", strFileName.c_str());
				RemoveFilesWithinDirectory(strTemp.c_str());
			}
			else
			{
				DeleteFileA(strTemp.c_str());
			}
		}
	}
	FindClose(hFile);

	RemoveDirectoryA(TmpDirPath.c_str());
}
